package com.jt.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @Aspect注解描述的类我们称之为切面对象,此对象负责定义切入点和通知
 * 1)切入点(在哪些方法执行时我们进行功能扩展-锦)
 * 2)通知(所有的扩展逻辑都会写到通知方法中-花)
 */
@Aspect
@Component
public class LogAspect {
    /**
     * 通过@Pointcut注解定义定义切入点表达式,表达式的写法有多种,比较常用
     * 有注解方式的表达式(@annotation(你自己定义的注解)).当使用自己写
     * 的注解对方法进行描述时,这个方法就是切入点方法.在这个方法上要锦上添花
     */
    @Pointcut("@annotation(com.jt.aop.RequiredLog)")
    public void doLog(){}//这个方法没有意义,主要用于承载切入点

    /**
     * Around通知,在此通知内部可以定义我们扩展业务逻辑,还可以调用目标执行链
     * @param joinPoint 连接点(通知方法与目标方法的连接点对象),ProceedingJoinPoint
     *   类型的连接点只能应用在Around通知方法中.
     * @return
     * @throws Throwable
     */
    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint joinPoint)
    throws Throwable{
         System.out.println("Before:"+System.currentTimeMillis());
         Object result=joinPoint.proceed();//执行链(其它切面,目标对象方法)
         System.out.println("After:"+System.currentTimeMillis());
         return result;
    }

}
